# -*-coding: utf-8 -*-
"""
    @Theme   : Migrate code to asyncio by combining threads and coroutines
    @Time    : 2023/12/14 21:23
    @Author  : YamFish
    @Url     : https://www.zhihu.com/people/yamfish
"""
import time
from threading import Lock, Thread

import click

from write import setup, confirm_merge


class NoNewData(Exception):
    pass


def readline(handle):
    offset = handle.tell()

    handle.seek(0, 2)
    length = handle.tell()

    if length == offset:
        raise NoNewData

    handle.seek(offset, 0)
    return handle.readline()


def tail_file(handle, interval, write_func):
    while not handle.closed:
        try:
            line = readline(handle)
        except NoNewData:
            time.sleep(interval)
        else:
            write_func(line)


def run_threads(read_handles, interval, merged_path):
    with open(merged_path, 'wb') as output:
        lock = Lock()

        def write(data):
            with lock:
                print(data.decode(), end='')
                output.write(data)

        threads = []
        for handle in read_handles:
            thread = Thread(target=tail_file, args=(handle, interval, write))
            thread.start()
            threads.append(thread)

        for thread in threads:
            thread.join()


@click.command()
@click.option('--sleep', default=0, help='you kan check the tmpdir files.', type=float)
@click.option('--files', default=5, help='the number of files.', type=int)
@click.option('--verbose', is_flag=True, help='show more details.')
def main(sleep, files, verbose):
    """Merge multiple input streams into one output stream"""
    tmpdir, input_paths, handles, output_path = setup(files)
    run_threads(handles, 0.1, output_path)

    if verbose:
        print('Confirm Merge Result: \n')
    confirm_merge(input_paths, output_path, verbose=verbose)

    time.sleep(sleep)
    tmpdir.cleanup()


if __name__ == "__main__":
    main()
